package dao;

import model.Train;
import java.sql.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static dao.BaseDao.executeUpdate;
import static dao.BaseDao.getConnection;

/**
 * 列车数据访问对象
 */
public class TrainDao {
    // 修改表结构，添加车厢座位信息
    public static void initDatabase() {
        try (Connection conn = getConnection()) {
            // 修改列车表，添加车厢座位信息
            String alterTable = "ALTER TABLE trains ADD COLUMN 车厢座位信息 TEXT";
            try {
                executeUpdate(conn, alterTable);
            } catch (SQLException e) {
                // 表可能已存在，忽略错误
            }
            System.out.println("列车表结构更新完成");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // 添加列车
    public boolean addTrain(Train train) {
        String sql = "INSERT INTO trains (车次, 出发地, 目的地, 出发时间, " +
                "到达时间, 总座位数, 可用座位数, 票价, 车厢座位信息) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, train.getTrainNumber());
            pstmt.setString(2, train.getDeparture());
            pstmt.setString(3, train.getDestination());
            pstmt.setTimestamp(4, new Timestamp(train.getDepartureTime().getTime()));
            pstmt.setTimestamp(5, new Timestamp(train.getArrivalTime().getTime()));
            pstmt.setInt(6, train.getTotalSeats());
            pstmt.setInt(7, train.getAvailableSeats());
            pstmt.setDouble(8, train.getPrice());

            // 保存车厢座位信息
            int[] carriageSeats = train.getCarriageSeats();
            StringBuilder seatsStr = new StringBuilder();
            for (int i = 0; i < carriageSeats.length; i++) {
                seatsStr.append(carriageSeats[i]);
                if (i < carriageSeats.length - 1) {
                    seatsStr.append(",");
                }
            }
            pstmt.setString(9, seatsStr.toString());

            return pstmt.executeUpdate() > 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 获取所有列车信息
    public List<Train> getAllTrains() {
        List<Train> trains = new ArrayList<>();
        String sql = "SELECT * FROM trains";
        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql);
             ResultSet rs = pstmt.executeQuery()) {
            while (rs.next()) {
                trains.add(mapTrain(rs));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return trains;
    }

    // 根据出发地、目的地和日期查询列车
    public List<Train> findByDepartureAndDestination(String departure, String destination, Date date) {
        List<Train> trains = new ArrayList<>();
        String sql = "SELECT * FROM trains WHERE 出发地 = ? AND 目的地 = ? " +
                "AND DATE(出发时间) = ? AND 可用座位数 > 0";
        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, departure);
            pstmt.setString(2, destination);
            pstmt.setDate(3, new java.sql.Date(date.getTime()));
            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    trains.add(mapTrain(rs));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return trains;
    }

    // 根据ID获取列车
    public static Train getById(int id) {
        String sql = "SELECT * FROM trains WHERE id = ?";
        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, id);
            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    return mapTrain(rs);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    // 更新列车座位数（带事务）
    public static boolean updateSeats(Connection conn, int trainId, int newAvailableSeats) {
        String sql = "UPDATE trains SET 可用座位数 = ? WHERE id = ?";
        try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, newAvailableSeats);
            pstmt.setInt(2, trainId);
            return pstmt.executeUpdate() > 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 更新列车座位数（不带事务，用于非事务操作）
    public static boolean updateSeats(int trainId, int newAvailableSeats) {
        try (Connection conn = BaseDao.getConnection()) {
            return updateSeats(conn, trainId, newAvailableSeats);
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    // 将结果集映射为列车对象
    private static Train mapTrain(ResultSet rs) throws SQLException {
        Train train = new Train();
        train.setId(rs.getInt("id"));
        train.setTrainNumber(rs.getString("车次"));
        train.setDeparture(rs.getString("出发地"));
        train.setDestination(rs.getString("目的地"));
        train.setDepartureTime(rs.getTimestamp("出发时间"));
        train.setArrivalTime(rs.getTimestamp("到达时间"));
        train.setTotalSeats(rs.getInt("总座位数"));
        train.setAvailableSeats(rs.getInt("可用座位数"));
        train.setPrice(rs.getDouble("票价"));

        // 解析车厢座位信息
        String carriageSeatsStr = rs.getString("车厢座位信息");
        if (carriageSeatsStr != null && !carriageSeatsStr.isEmpty()) {
            String[] parts = carriageSeatsStr.split(",");
            int[] carriageSeats = new int[parts.length];
            for (int i = 0; i < parts.length; i++) {
                carriageSeats[i] = Integer.parseInt(parts[i]);
            }
            train.setCarriageSeats(carriageSeats);
        }
        return train;
    }

    // 更新列车座位占用状态
    public boolean updateSeatOccupancy(int trainId, int seatNumber) {
        String sql = "UPDATE trains SET seat_occupancy = SET_BIT(seat_occupancy, ?, 1) WHERE id = ?";
        try (Connection conn = getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, seatNumber - 1); // 座位号从 1 开始，数组索引从 0 开始
            pstmt.setInt(2, trainId);
            return pstmt.executeUpdate() > 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }
}